<?php

namespace App;

use Illuminate\Support\Facades\Cache;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Log;


class Menu extends Model
{
    use SoftDeletes;

    /**
     * 需要转换成日期的属性
     * @var array
     */
    protected $dates = ['deleted_at'];

    /**
     * menus 表更新时调用
     */
    static public function CacheUpdate() {
        Cache::forget('MenusRouterData');
        Cache::forget('MenusAllDataTree');
        Cache::forget('MenusPrimaryData');
        Cache::forget('MenusListData');
        Cache::forget('MenusAllKeyData');
        Cache::forget('UserRoleCache');     //所有工作人员权限菜单缓存
    }

    /**
     * 所有菜单id集合
     * @return array
     * @author: lxy
     * @time: 2020/6/8 2:14 下午
     * @流程:
     */
    static public function GetMenusAllKeyData() {
        $cacheName = 'MenusAllKeyData';
        $Menus = Cache::get($cacheName);
        if (empty($Menus)) {
            $list = Menu::select('id')->get()->toArray();
            $list = array_column($list,'id');
            $Menus = array_flip($list);
            Cache::put($cacheName,$Menus);
        }
        return $Menus;
    }


    /**
     * 获取菜单列表
     * @param int $pid
     * @return array
     * @author: lxy
     * @time: 2020/6/5 10:43 上午
     * @流程:
     */
    static public function GetList(int $pid) : array {
        $cacheName = 'MenusListData';
        $Menus = Cache::get($cacheName);
        if (empty($Menus)) {
            $Menus = DB::table('menus')
                ->leftJoin('menus as parent', 'parent.id', '=', 'menus.pid')
                //->where('menus.pid',$pid)
                ->where('menus.deleted_at',null)
                ->select('menus.*','parent.title as parent_title')
                ->orderBy('menus.sort','desc')
                ->get()
                ->toArray();

            $Menus = array_group($Menus,'pid');
            Cache::forever($cacheName,$Menus);
        }
        return [
            'ok'      => true,
            'list'    => $Menus[$pid]
        ];
    }

    /**
     * 获取初级菜单
     * @return array
     * @author: lxy
     * @time: 2020/6/5 10:41 上午
     * @流程:
     */
    static public function GetPrimary() : array {
        $cacheName = 'MenusPrimaryData';
        $Menus = Cache::get($cacheName);
        if (empty($Menus)) {
            $list = Menu::where('level','<',2 )
                ->where('status',1)
                ->orderBy('sort','desc')
                ->get()
                ->toArray();
            $list = array_to_tree($list);
            $Menus = [];
            foreach ($list as $group ) {
                $Menus[] = &$group;
                if (isset($group['_child'])) {
                    foreach ($group['_child'] as $item) {
                        $item['title'] = '--|'.$item['title'];
                        $Menus[] = $item;
                        unset($group['_child']);
                    }
                }
                unset($group);
            }
            Cache::forever($cacheName,$Menus);
        }

        return  [
            'ok'   => true,
            'list' => $Menus
        ];
    }

    /**
     * 更新菜单状态 启用｜禁用
     * @param array $data
     * @return array
     * @author: lxy
     * @time: 2020/6/5 10:48 上午
     * @流程:
     */
    static public function UpdateStatus(array $data) : array {
        try {
            if (!is_numeric($data['id'])) {
                throw new \Exception('请选择操作信息');
            }

            if (!is_numeric($data['status'])) {
                throw new \Exception('请选择更新状态');
            }
            $res = Menu::where('id',$data['id'])->update(['status' => $data['status']]);
            if (!is_numeric($res)) {
                throw new \Exception('数据库更新失败');
            }

            self::CacheUpdate();

            $result = [
                'ok'  => true,
                'msg' => '操作完成'
            ];

        } catch (\Exception $e){
            $result = [
                'ok'  => false,
                'msg' => $e->getMessage()
            ];
        }

        return $result;
    }

    /**
     * 删除菜单
     * @param $id
     * @return array
     * @author: lxy
     * @time: 2020/6/5 11:13 上午
     * @流程:
     */
    static public function DelMenus($id) : array {
        $res = Menu::where('id',$id)->orWhere('pid',$id)->delete();
        if ($res) {
            self::CacheUpdate();
            $result = [
                'ok'  => true,
                'msg' => '操作完成'
            ];
        } else {
            $result = [
                'ok'  => false,
                'msg' => '数据库更新失败'
            ];
        }
        return $result;
    }

    /**
     * 菜单树形结构
     * @return array
     * @author: lxy
     * @time: 2020/6/5 2:31 下午
     * @流程:
     */
    static public function MenusTree() {
        $cacheName = 'MenusAllDataTree';
        $MenusTree = Cache::get($cacheName);
        if (empty($MenusTree)) {
            $list = Menu::orderBy('sort','DESC')
                ->where('status',1)
                ->select('id as value','id as key','pid','title')
                ->get()
                ->toArray();
            $MenusTree = array_to_tree($list,'value','pid','children');
            Cache::forever($cacheName,$MenusTree);
        }

        return  [
            'ok'   => true,
            'list' => $MenusTree
        ];
    }


    /**
     * 获取路由信息
     * @param int $group_id 即 父级id（三级菜单） ， 0 则返回二级菜单
     * @return mixed
     */
    static public function MenusAllData(int $group_id=0) {
        $cacheName = 'MenusRouterData';
        $Menus = Cache::get($cacheName);
        if (empty($Menus)) {
            $list = Menu::orderBy('sort','DESC')
                ->where('status',1)
                ->where('router','<>','')
                ->get()
                ->toArray();
            $Menus = [];
            //将菜单根据父级分组，并以路由及参数为key
            foreach ($list as $val) {
                $key = empty($val['param_str']) ? $val['router'] : $val['router'].'?'.$val['param_str'];
                $Menus[$val['pid']][$key] = $val;
                if ($val['level'] < 2) {
                    $Menus[0][$key] = $val;
                }
            }
            Cache::forever($cacheName,$Menus);
        }

        return isset($Menus[$group_id]) ? $Menus[$group_id] : [];
    }


    /**
     * 获取用户菜单权限数组
     * @param \Illuminate\Contracts\Auth\Authenticatable $user
     * @return array
     * @author: lxy
     * @time: 2020/6/8 11:42 上午
     * @流程:
     */
    static public function getUserMenus(\Illuminate\Contracts\Auth\Authenticatable $user) : array {
        //cache key
        $userRoleCacheKey = 'UserRoleCache';
        //所有工作人员权限菜单缓存
        $UserRoleMenus = Cache::get($userRoleCacheKey);
        //查询当前用户拥有权限组
        if (!isset($UserRoleMenus[$user->id])) {
            $roleGroup = $user->role_group;
            if (empty($roleGroup)) {
                Log::debug("$user->username 未分配权限");
                return [];
            }

            $roleIds = explode(',',$roleGroup);
            //查询权限组信息
            $roleList = Role::whereIn('id',$roleIds)
                ->where('status',1)
                ->get()
                ->toArray();

            if (empty($roleList)) {
                Log::debug("$user->username 权限组查询异常");
                return [];
            }

            $RoleMenus = array_column($roleList,'power');
            $RoleMenus = implode(',',$RoleMenus);
            $RoleMenus = explode(',',$RoleMenus);
            $RoleMenus = array_unique($RoleMenus);
            $RoleMenus = array_flip($RoleMenus);
            $menuIds = array_keys($RoleMenus);
            $RoleMenus = self::getParents($menuIds);
            $UserRoleMenus[$user->id] = $RoleMenus;
            Cache::forever($userRoleCacheKey,$UserRoleMenus);
        }

        return $UserRoleMenus[$user->id];
    }



    static private function getParents(array $ids){
        $temp = Menu::whereIn('id',$ids)
            ->where('status',1)
            ->select('pid')
            ->get()
            ->toArray();
        $pids = array_column($temp,'pid');
        $temp = Menu::whereIn('id',$pids)
            ->where('status',1)
            ->select('pid')
            ->get()
            ->toArray();
        $pids2 = array_column($temp,'pid');
        $ids = array_merge($ids,$pids,$pids2);
        $return = [];
        foreach ($ids as $val) {
            $return[$val] = true;
        }
        return $return;
    }

}